﻿using FlexFlow.Base;
using FlexFlow.Base.Interface;
using FlexFlow.Model;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FlexFlow.DataProvider.MongoDB
{
    public class MongoDbProcessProvider : MongoDBPhysicalModelProvider<Process>, IProcessProvider
    {
        public override Process Create()
        {
            return new Process()
            {
                CreateTime = DateTime.Now,
                State = ProcessState.Created,
                Message = "等待编译"
            };
        }
        /// <summary>
        /// 判断指定的文件Id的文件是否已经作为流程使用
        /// </summary>
        /// <param name="fileId">
        /// 要判断的文件Id
        /// </param>
        /// <returns>
        /// 一个值，表示文件是否已经作为流程使用
        /// </returns>
        public bool CheckFileInstalled(Guid fileId)
        {
            var col = GetCollection();
            FilterDefinition<Process> filter = (FilterDefinition<Process>)(m => m.PhysicalFileId == fileId);
            return col.FirstOrDefault(filter) != null;
        }
        /// <summary>
        /// 取得指定的文件安装后的流程
        /// </summary>
        /// <param name="fileId">
        /// 要取得的流程模板的文件ID
        /// </param>
        /// <param name="state">
        /// 要取得的流程的状态
        /// </param>
        /// <returns>
        /// 取得的流程
        /// </returns>
        public Process GetByFileId(Guid fileId, ProcessState? state = null)
        {
            FilterDefinition<Process> filterDef;
            if (state == null)
            {
                filterDef = (FilterDefinition<Process>)(m => m.PhysicalFileId == fileId);
            }
            else
            {
                filterDef = (FilterDefinition<Process>)(m => m.PhysicalFileId == fileId && m.State == state);
            }
            var col = GetCollection();
            return col.FirstOrDefault(filterDef);
        }
        /// <summary>
        /// 取得一个未编译的模板信息并更新其编译信息为 Installing
        /// </summary>
        /// <returns>
        /// 取得的模板信息
        /// </returns>
        public Process GetAndSetState()
        {
            var col = GetCollection();
            FilterDefinition<Process> filter = (FilterDefinition<Process>)(m => m.State == ProcessState.Created);
            Process temp = col.FirstOrDefault(filter);

            if (temp == null)
                return null;

            temp.State = ProcessState.Installing;

            if (!UpdateState(temp.Identity, ProcessState.Installing, "正在安装"))
            {
                return null;
            }

            return temp;
        }
        /// <summary>
        /// 更新指定模板的状态及消息
        /// </summary>
        /// <param name="state">
        /// 要更新的状态
        /// </param>
        /// <param name="message">
        /// 状态消息
        /// </param>
        /// <returns>
        /// 更新是否成功
        /// </returns>
        public bool UpdateState(Guid id, ProcessState state, string message)
        {
            var updef = BuildUpdateDef(m => m.State, state);
            updef = BuildUpdateDef(m => m.Message, message, updef);
            return Update(id, updef);
        }

        /// <summary>
        /// 取得所有的流程定义的ID
        /// </summary>
        /// <param name="state">
        /// 流程状态
        /// </param>
        /// <returns>
        /// 取得的流程定义ID列表
        /// </returns>
        public List<Guid> GetAllID(ProcessState state)
        {
            return this.GetCollection().AsQueryable().Where(m => m.State == state).Select(m => m.Identity).ToList();
        }
    }
}
